﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI.HtmlControls;
using JqueryNet.FormControl.FormHtmlControl;
using JqueryNet.FormControl.FormWebControl;
using System.Web.UI.WebControls;
using System.Reflection;
using System.Linq.Expressions;

namespace JqueryNet
{
    public abstract class JHtmlContainerControl : JHtmlControl
    {
        HtmlContainerControl _Html;

        public JHtmlContainerControl(HtmlContainerControl _html)
            : base(_html)
        {
            this._Html = _html;
        }

        public override void Html()
        {
            Value = _Html.InnerHtml;
        }

        public override void Html(string value)
        {
            _Html.InnerHtml = value;
        }

        public override void Text()
        {
            Value = _Html.InnerText;
        }

        public override void Text(string value)
        {
            _Html.InnerText = value;
        }


    }

    public abstract class JHtmlInputControl : JHtmlControl
    {
        public HtmlInputControl _Html;
        public JHtmlInputControl(HtmlInputControl _html)
            : base(_html)
        {
            _Html = _html;
        }

        public void GetName()
        {
            Value = _Html.Name;
        }

        public void SetName(string value)
        {
            _Html.Name = value;
        }

        public void GetValue()
        {
            Value = _Html.Value;
        }

        public void SetValue(string value)
        {
            _Html.Value = value;
        }

        public override void Val(string value)
        {
            SetValue(value);
        }

        public override void Val()
        {
            GetValue();
        }

        public override void Attr(string key)
        {
            switch (key.ToLower())
            {
                case "name":
                    GetName(); return;
                case "value":
                    GetValue(); return;
                default:
                    base.Attr(key); return;
            }
        }

        public override void Attr(string key, string value)
        {
            bool f;
            bool.TryParse(value, out f);
            switch (key.ToLower())
            {
                case "name":
                    SetName(value); return;
                case "value":
                    SetValue(value); return;
                default:
                    base.Attr(key, value); return;
            }
        }
    }

    public abstract class JListControl : JWebControl
    {
        ListControl _Web;
        public JListControl(ListControl _web)
            : base(_web)
        {
            this._Web = _web;
        }

        public override void Clear()
        {
            _Web.ClearSelection();
        }

        public override void Val()
        {
            if (_Web.DataSource != null)
            {
                List<ListItem> list = new List<ListItem>();
                foreach (ListItem item in _Web.Items)
                {
                    list.Add(item);
                }
            }
            else
            {
                base.Val();
            }
        }

        public override void Val(string value)
        {
            if (_Web.DataSource != null)
            {
                _Web.Items.Add(value);
            }
            else
            {
                base.Val(value);
            }
        }

    }

    public static class BindEventClass
    {
        public static void BindEvent(object tag, string eventname, Delegate dele)
        {
            //事件需要的参数转换

            var even = tag.GetType().GetEvent(eventname, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
            var delegateType = even.EventHandlerType;
            MethodInfo invokeMethod = delegateType.GetMethod("Invoke");
            ParameterInfo[] parameters = invokeMethod.GetParameters();
            
            ParameterExpression[] paramsExp = new ParameterExpression[parameters.Length];//参数构造成ParameterExpression
            Expression[] argsArrayExp = new Expression[parameters.Length];//ParameterExpression转换成objec
            for (int i = 0; i < parameters.Length; i++)
            {
                paramsExp[i] = Expression.Parameter(parameters[i].ParameterType, parameters[i].Name);
                //argsArrayExp[i] = Expression.Convert(paramsExp[i], typeof(Object));
            }
            //事件需要的委托            
            var executeMethod = dele.Method;

            Expression lambdaBodyExp =
            Expression.Call(Expression.Constant(dele.Target), executeMethod, paramsExp);

            //如果有返回值，那么将返回值转换成委托要求的类型
            //如果没有返回值就这样搁那里就成了
            if (!invokeMethod.ReturnType.Equals(typeof(void)))
            {
                //这是有返回值的情况 
                lambdaBodyExp = Expression.Convert(lambdaBodyExp, invokeMethod.ReturnType); //执行方法后转换返回值
            }

            LambdaExpression dynamicDelegateExp = Expression.Lambda(delegateType, lambdaBodyExp, paramsExp);

            //我们创建的Expression是这样的一个函数：
            //(委托的参数们) => GeneralHandler(new object[] { 委托的参数们 })

            //编译
            Delegate dynamiceDelegate = dynamicDelegateExp.Compile();
            even.AddEventHandler(tag, dynamiceDelegate);
        }
    }

}
